package com.shigu.mo.actions;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.shigu.agent.enums.UserRoleType;
import com.shigu.component.shiro.AuthorityUser;
import com.shigu.mo.enums.SessionEnum;
import com.shigu.mo.exceptions.MoException;
import com.shigu.mo.services.OverallSituationService;
import com.shigu.mo.services.UserBaseService;
import com.shigu.mo.utils.MatrixUtil;
import com.shigu.wx.web.SnsOauth2Access_tokenGet;
import com.shigu.wx.web.WebToken;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.sword.wechat4j.api.WechatClient;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.ws.RespectBinding;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Hashtable;

/**
 * 用户设置
 */
@Controller
public class UserBaseController implements Serializable{
    private static final Logger logger = LoggerFactory.getLogger(UserBaseController.class);

    @Value("${wechat.appid}")
    private String APP_ID;

    @Value("${wechat.appsecret}")
    private String APP_SECRET;

    @Value("${main_host}")
    private String MAIN_HOST;

    @Value("${wx.public.qrimg}")
    private String QRIMG;

    @Value("${wap.qrcodeURL}")
    private String QRCODE_URL;

    @Value("${me.logoTxt}")
    private String logoTxt;

    @Autowired
    private UserBaseService userBaseService;

    @RequestMapping({"buspage/*","buspage/*/*","buspage/*/*/*","agpage/*","agpage/*/*","agpage/*/*/*"})
    public String wapIndex(HttpServletRequest request,HttpSession session, Model model) throws UnsupportedEncodingException {
        String uri=request.getRequestURI();
        if (uri.endsWith("buspage/userInvite")) {
            model.addAttribute("title","邀请好友");
            return "invite";
        }
        if (uri.endsWith("agpage/agentInvite")){
            model.addAttribute("title","拓展商户");
            return "invite";
        }
        String agentFlag="agpage/agentInvite/";
        if (uri.contains(agentFlag)){
            model.addAttribute("title","拓展商户");
            model.addAttribute("fromId",uri.substring(uri.indexOf(agentFlag)+agentFlag.length(),uri.length()));
            return "invite";
        }
        //如果登陆了，去登陆页面，直接跳入
        AuthorityUser auth= (AuthorityUser) session.getAttribute(SessionEnum.LOGIN_USER.toString());
        //代理的
        if (auth != null) {
            Subject currentUser = SecurityUtils.getSubject();
            if(uri.startsWith("/wappage/agpage/agentLogin")&&currentUser.hasRole(UserRoleType.AGENT.getValue())){//代理登陆页面
                return parseLoginedUrl(uri,"/wappage/agpage/agentLogin","http!3A!2F!2F","wappage/agpage/agent");
            }else if(uri.startsWith("/wappage/buspage/login")&&currentUser.hasRole(UserRoleType.BUSINESS.getValue())){//商户登陆页面
                return parseLoginedUrl(uri,"/wappage/buspage/login","http!3A!2F!2F","wappage/buspage/index");
            }else if(uri.contains("/wappage/buspage/regedit")&&currentUser.hasRole(UserRoleType.BUSINESS.getValue())){
                return "redirect:"+MAIN_HOST+"wappage/buspage/index";
            }
        }else if(uri.contains("/wappage/buspage/regedit/from")){//代理发展现商户不仅限于第一跳
            session.setAttribute(SessionEnum.FROM_SPREADWAY.toString(),uri.replace("/wappage/buspage/regedit/",""));
        }
        return "wapIndex";
    }

    /**
     * 计算已登陆页面的重定向方案
     * @param uri
     * @param startFlag
     * @param containFlag
     * @param emptyTo
     * @return
     * @throws UnsupportedEncodingException
     */
    private String parseLoginedUrl(String uri,String startFlag,String containFlag,String emptyTo) throws UnsupportedEncodingException {
            if (uri.contains(containFlag)) {
                String url=uri.replace(startFlag+"/","").replace("!","%");
                return "redirect:"+URLDecoder.decode(url,"UTF-8");
            }else{
                return "redirect:"+MAIN_HOST+emptyTo;
            }
    }

    @RequestMapping("changepwd")
    @RequiresPermissions("set:changepwd")
    public String changepwd(){
        return "mo/changepwd";
    }

    @Autowired
    private OverallSituationService overallSituationService;

    /**
     * 给用户微信绑定
     * @param state
     * @param session
     * @throws IOException
     */
    @RequestMapping("userBindWx")
    public String userBindWx(String state, HttpSession session) throws IOException {
        AuthorityUser auth= (AuthorityUser) session.getAttribute(SessionEnum.LOGIN_USER.toString());
        String openid= (String) session.getAttribute(SessionEnum.WX_LOGEDUSER.toString());
        if(userBaseService.hasFollow(openid,auth.getUserId())){//已经关注
            return "redirect:"+ URLDecoder.decode(state,"utf-8");
        }else{
            return "redirect:"+MAIN_HOST+"wap/promotion.htm";
        }
        //观测是否关注，如果没有关注跳关注
    }


    @RequestMapping("wxlogin")
    public  String wxlogin(String code,String state,HttpSession session) throws IOException {
        WebToken token=userBaseService.mkWebToken(code);
        if (token == null) {
            return "redirect:/wappage/buspage/login";
        }
        session.setAttribute(SessionEnum.WX_LOGEDUSER.toString(),token.getOpenid());
        if (state.contains("!")) {
            state=state.replace("!","%");
        }
        return "redirect:"+ URLDecoder.decode(state,"utf-8");
    }


    @RequestMapping("loginByWx")
    public String loginByWx(String state,HttpSession session) throws IOException, MoException {
        String openid= (String) session.getAttribute(SessionEnum.WX_LOGEDUSER.toString());
        userBaseService.loginByWx(openid);
        return "redirect:"+ URLDecoder.decode(state,"utf-8");
    }

    /**
     * 检测微信绑定情况
     * 如果授权过了直接跳回调
     * @param type 1  nologin，2检测登陆，如果没登陆的之前绑定过，本此自动登陆
     * @return
     */
    @RequestMapping("toWxBind")
    public String toWxBind(String backUrl,Integer type,HttpSession session) throws UnsupportedEncodingException {
        if(type!=null&&type==2){
            AuthorityUser auth= (AuthorityUser) session.getAttribute(SessionEnum.LOGIN_USER.toString());
            if (auth != null) {
                return "redirect:"+URLDecoder.decode(backUrl,"utf-8");
            }
            return "redirect:"+MAIN_HOST+"loginByWx.htm?state="+ (StringUtils.isEmpty(backUrl)?"":URLEncoder.encode(backUrl,"utf-8"));
        }
        return "redirect:"+MAIN_HOST+"userBindWx.htm?state="+ (StringUtils.isEmpty(backUrl)?"":URLEncoder.encode(backUrl,"utf-8"));
    }

    @RequestMapping("wap/qrimg")
    public void qrImg(String fromId,HttpSession session, HttpServletResponse response) throws WriterException, IOException {
        if (StringUtils.isEmpty(fromId)) {
            AuthorityUser auth= (AuthorityUser) session.getAttribute(SessionEnum.LOGIN_USER.toString());
            fromId=auth.getUserId().toString();
        }

        String qrUrl=MAIN_HOST+"wappage/buspage/regedit/from"+fromId;
        int width = 300; // 二维码图片宽度
        int height = 300; // 二维码图片高度
        String format = "jpg";// 二维码的图片格式

        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 内容所使用字符集编码
        hints.put(EncodeHintType.MARGIN, 1);
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(qrUrl,
                BarcodeFormat.QR_CODE, width, height, hints);
        response.setContentType("image/png");
        OutputStream stream = response.getOutputStream();
        ImageIO.write(MatrixUtil.toBufferedImage(bitMatrix),format,stream);
        stream.flush();
        stream.close();
    }

    @RequestMapping("wap/promotion")
    public String promotion(Model model){
        model.addAttribute("logoTxt",logoTxt);
        return "promotion";
    }

    @RequestMapping("wxQrImg")
    public String wxQrImg(){
        return "redirect:"+QRIMG;
    }

    @RequestMapping("bus/qrCodeConBack")
    public String qrCodeConBack(){
        return "redirect:"+QRCODE_URL;
    }

    /**
     * 全局设置重置
     * @return
     */
    @RequestMapping("configinit")
    @ResponseBody
    public String reloadSituation(){
        overallSituationService.reload();
        return "SUCCESS";
    }
    
}
